package com.wujilee.dbredissyn.service.impl;

import com.wujilee.dbredissyn.entity.EntityUser;
import com.wujilee.dbredissyn.exception.BusinessException;
import com.wujilee.dbredissyn.mapper.EntityUserMapper;
import com.wujilee.dbredissyn.service.RedisSynService;
import com.wujilee.dbredissyn.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @author liwuji
 * @date 2024/5/14
 * @desc
 **/
@Service
public class UserServiceImpl implements UserService {
    private final static String PREFIX = "USER:ID";
    @Resource
    private EntityUserMapper userMapper;
    @Resource
    private RedisSynService redisSynService;
    @Resource
    private RedisTemplate redisTemplate;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean save(EntityUser entityUser) {
        if (StringUtils.isEmpty(entityUser.getId())) {
            userMapper.insert(entityUser);
            return true;
        }
        userMapper.updateById(entityUser);
        redisSynService.deleteValue(PREFIX, entityUser.getId());
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delete(EntityUser entityUser) {
        int i = userMapper.updateById(entityUser);
        if (i != 1) {
            new BusinessException("删除失败，数据不存在或已被删除!");
        }
        redisSynService.deleteValue(PREFIX, entityUser.getId());
        return true;
    }

    @Override
    public EntityUser getUser(String id) {
        return redisSynService.getValue(PREFIX, id, EntityUser.class, user -> {
            // 防止缓存击穿 可以优化 改用读写锁
            synchronized (this) {
                String str = (String) redisTemplate.opsForValue().get(id);
                if (str == null) {
                    user = userMapper.selectById(id);
                    if (user == null) {
                        redisSynService.putValue(PREFIX, user.getId(), user, 60L);
                    } else {
                        // 缓存穿透问题
                        redisSynService.putValue(PREFIX, user.getId(), "", 60L);
                    }
                } else {
                    if ("".equals(str)) {
                        return null;
                    }
                }
                return user;
            }
        });
    }

}
